import React, { Component } from 'react'
import { Animated, StyleSheet, View, BackHandler, LayoutAnimation } from 'react-native'
import RootSiblings from 'react-native-root-siblings'
import CustomButton from 'src/components/button/CustomButton'
import TipPrompt from 'src/components/tip-prompt/index'
import { ScaleS, IS_IPHONEX } from './ScreenUtil'
import SelectModal from '../components/select-modal/index'
import ImageViewerModal from '../components/image-viewer/index'
import { isFunction } from './JSTypeUtil'
import UsefulExpressions from 'src/components/modal/UsefulExpressions'
import PropTypes from 'prop-types'

class ModalView extends Component {
  static defaultProps = {
    isFullHeight: false
  }

  static propTypes = {
    backgroundColor: PropTypes.string,
    children: PropTypes.element,
    onMaskPress: PropTypes.func,
    isFullHeight: PropTypes.bool
  }

  constructor (props) {
    super(props)
    this.state = {
      opacity: 0,
      top: 0
    }
    this.duration = 200
    this.viewHeight = 0
    this.opacityAnimate = new Animated.Value(0) // 动画 值初始化
    this.customLinear = {
      duration: this.duration,
      create: {
        type: LayoutAnimation.Types.linear,
        property: LayoutAnimation.Properties.opacity
      },
      update: {
        // type: LayoutAnimation.Types.easeInEaseOut
        type: LayoutAnimation.Types.linear
      }
    }
  }

  UNSAFE_componentWillUpdate () {
    LayoutAnimation.configureNext(this.customLinear)
  }

  render () {
    const { top } = this.state
    const { backgroundColor = 'rgba(0,0,0,0.7)', children, isFullHeight } = this.props
    return (
      <CustomButton style={styles.tipMask} onPress={this._onMaskPress} activeOpacity={1}>
        <Animated.View style={[styles.emptyView, { backgroundColor, opacity: this.opacityAnimate }]}/>
        <View onLayout={this._onLayout} style={[styles.animateView, { top, height: isFullHeight ? '100%' : 'auto' }]}>
          <CustomButton activeOpacity={1} style={{ height: isFullHeight ? '100%' : 'auto' }}>
            {children}
          </CustomButton>
        </View>
      </CustomButton>
    )
  }

  componentDidMount () {
    console.info('componentDidMount')
  }

  _onLayout = (e) => {
    const height = e.nativeEvent.layout.height
    if (this.viewHeight < height) {
      this.viewHeight = height
      // 开启动画
      this.setState({
        top: -height
      })
      Animated.timing(this.opacityAnimate, {
        toValue: 1,
        duration: this.duration
        // easing: Easing.ease
      }).start()
    }
  }

  _onMaskPress = () => {
    const { onMaskPress } = this.props
    this.closeModal(onMaskPress)
  }

  closeModal = (callBack) => {
    Animated.timing(this.opacityAnimate, {
      toValue: 0,
      duration: this.duration
      // easing: Easing.ease
    }).start()
    this.setState({
      top: 0
    }, () => {
      setTimeout(() => {
        callBack && callBack()
      }, this.duration)
    })
  }
}

/**
 * 显示modal带上滑动画
 * @param popModal
 * @param backgroundColor
 * @returns {{sibling: *, close: closeModal, update: updateModal}}
 */
export function showModal (PopModal, { backgroundColor = 'rgba(0,0,0,0.7)', isFullHeight = false, maskPressClose } = {}) {
  var sibling = null
  sibling = new RootSiblings(
    <ModalView ref={modalViewRef} onMaskPress={_maskPressClose} isFullHeight={isFullHeight}>
      {isFunction(PopModal) ? <PopModal closeModal={closeModal} hideModal={hideModal}/> : PopModal}
    </ModalView>
  )
  function _maskPressClose () {
    hideModal()
    // maskClose()
    maskPressClose && maskPressClose()
  }
  const modal = {
    sibling: sibling,
    close: closeModal,
    update: updateModal
  }
  const backHandler = BackHandler.addEventListener('hardwareBackPress', handleBackPress)

  function handleBackPress () {
    closeModal()
    return true
  }

  var modalRef

  function modalViewRef (ref) {
    modalRef = ref
  }

  /**
   * 关闭Modal
   *
   */
  function closeModal (pickerClosed) {
    modalRef.closeModal(() => {
      hideModal()
      pickerClosed && pickerClosed()
    })
  }

  function updateModal (popModal) {
    if (this.sibling) {
      this.sibling.update(popModal, () => {
        console.info('updateModal')
      })
    }
  }

  function hideModal () {
    if (sibling instanceof RootSiblings) {
      sibling.destroy()
      sibling = null
      backHandler.remove()
    }
  }

  return modal
}

function wrapWithPadding (content) {
  return (
    <View style={styles.wrapPaddingView}>
      {content}
    </View>
  )
}

/**
 * 显示提示的Modal
 * @param onCancel 取消回调
 * @param onConfirm 确认回调
 * @param confirmText 确认文本
 * @param cancelText 取消文本
 * @param titleText 标题文本
 * @param contentText 内容文本
 */
export function showTipModal (config = {}) {
  return showModal(wrapWithPadding(<TipPrompt {...config}>{config.children}</TipPrompt>))
}

/**
 * 显示选择的Modal
 * @param onCancel 取消回调
 * @param titleText 标题文字
 * @param selectArr 选择文字数组
 * @param selectClick 选择的点击回调
 */
export function showSelectModal (config = {}) {
  return showModal(<SelectModal {...config}/>)
}

/**
 * 显示ImageViewer的Modal
 * @param onClose 关闭回调
 * @param images 图片数组
 * @param initIndex 初始的默认索引
 */
export function showImageViewerModal (config = {}) {
  return showModal(<ImageViewerModal {...config}/>, { backgroundColor: 'transparent', isFullHeight: true })
}

/**
 * 显示常用语编辑
 * @param config
 * @returns {{sibling: *, close: closeModal, update: updateModal}}
 */
export function showUsefulExpressions (config = {}, params = {}) {
  const { maskPressClose } = config
  const modalParams = {}
  if (maskPressClose) {
    modalParams.maskPressClose = maskPressClose
  }
  return showModal((props) => <UsefulExpressions {...props} {...config} params={params}/>, modalParams)
}

const styles = StyleSheet.create({
  tipMask: {
    position: 'absolute',
    top: 0,
    right: 0,
    bottom: 0,
    left: 0
  },
  emptyView: {
    height: '100%',
    backgroundColor: 'rgba(0,0,0,0.7)'
  },
  animateView: {
    position: 'relative',
    right: 0,
    top: 0,
    left: 0
  },
  wrapPaddingView: {
    paddingHorizontal: ScaleS(6),
    paddingBottom: IS_IPHONEX ? ScaleS(26) : ScaleS(6)
  }
})
